﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.ComponentModel.Composition.Hosting;
using Plugin_Interfaces;
using PMKB_DAL;
using PMKB_Repository;
using System.IO;

namespace PMKB_Web.pluginsCode
{
    /// <summary>
    /// worst practice this comment 
    /// created once from global.asax  - does not matter threading
    /// 
    /// </summary>
    public class PluginControllerFactory : DefaultControllerFactory
    {
        
        public static Dictionary<string,Type> Controllers { get; set; }
        
        
        public PluginControllerFactory(string path)
            : base()
        {
            Controllers = new Dictionary<string, Type>();
            try
            {

                var catalog = new AggregateCatalog(new DirectoryCatalog(path));
                CompositionContainer container = new CompositionContainer(catalog);
                foreach (var item in container.GetExports<Controller>())
                {
                    var cnt = item.Value;
                    var name = cnt.GetType().Name.ToLowerInvariant();
                    name=name.Replace("controller","");
                    Controllers.Add(name, cnt.GetType());
                }
            }
            catch (System.IO.DirectoryNotFoundException)
            {
                //TODO: log.
            }
        }

        public static object pluginFromName(string controllerName,string PathFiles)
        {
            Func<string, Type> find = (key) =>
            {
                key = key.ToLowerInvariant();
                if (Controllers.ContainsKey(key))
                {
                    return Controllers[key];
                }

                return null;
            };

            var ret = find(controllerName);
            if (ret == null)
            {
                ret = find(controllerName + "Controller");
            }
            if (ret != null)
            {
                var controller = Activator.CreateInstance(ret, SiteUtils.ConnectionString, PathFiles);
                var fileUpload = controller as AddObject;
                if (fileUpload != null)
                {
                    fileUpload.ObjectSaved += new EventHandler<EventString>(fileUpload_ObjectSaved);
                }
                return controller;
            }
            return null;
        }

        static void fileUpload_ObjectSaved(object sender, EventString e)
        {
            SavedFile(e.Value);
        }
        public override IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
        {

            var plugin = pluginFromName(controllerName, requestContext.HttpContext.Server.MapPath("~/files")) as IController;
            return plugin as IController?? base.CreateController(requestContext, controllerName); 
            
        }
        public static void SavedFile(String FileName)
        {
            LinkAddOrEdit a = new LinkAddOrEdit();
            a.IDSelectedTags = new List<long>();
            a.ConnectionName = SiteUtils.ConnectionString;
            var link = new PMKB_DAL.Link();
            link.LinkDescription = "file";
            link.LinkName = FileName;



            link.LinkUrl = FileName.Substring(HttpContext.Current.Server.MapPath(".").Length);
            using (Tag_List tl = new Tag_List(SiteUtils.ConnectionString))
            {


                tl.LoadFromDB.LoadFrom_TagName("file");
                var nr = tl.Count();
                if (nr == 0)
                {

                    tl.Add(new Tag() { TagName = "file" });
                    tl.SaveNew();
                }

                a.IDSelectedTags.Add(tl[0].TagID);
                tl.Clear();
                string ext = Path.GetExtension(FileName);
                tl.LoadFromDB.LoadFrom_TagName(ext);
                nr = tl.Count();
                if (nr == 0)
                {

                    tl.Add(new Tag() { TagName = ext });
                    tl.SaveNew();

                }
                a.IDSelectedTags.Add(tl[0].TagID);

            }

            a.link = link;
            a.SaveNew();
            //construct the URL for view
            string req = HttpContext.Current.Request.RawUrl.ToLower();
            if (req.EndsWith("/"))
                req = req.Substring(0, req.Length - 1);

            if (!req.EndsWith("index"))
                req = req + "/index";

            req = req.Replace("index", "view") + "/" + a.link.LinkID;

            a.link.LinkUrl = req;
            a.link.LinkCreationDate = DateTime.Now;
            a.Save();
        }
    }
}